<?php
/**
 * Result object with data manipulation methods
 *
 * @author Adam Zivner <adam.zivner@gmail.com>
 * @license http://www.opensource.org/licenses/bsd-license.php New BSD license
 * @package Query2
 * @link http://query2.0o.cz
 */

class Query2Result implements Iterator, Countable
{
	public $res;

	public function __construct($res)
	{
		$this->res = $res;
	}

	public function __destruct()
	{
		mysql_free_result($this->res);
	}

	/**
	 * Return first (or $col, if given) column of the first line of the result.
	 *
	 * @param string $col
	 * @return mixed
	 */

	public function fetchOne($col = "")
	{
		$row = mysql_fetch_assoc($this->res);

		if(!$row)
			return false;
		else
			return empty($col) ? reset($row) : $row[$col];
	}

	/**
	 * Fetch first (or $col, if given) column of all result rows.
	 *
	 * @param string $col
	 * @return array
	 */

	public function fetchCol($col = "")
	{
		$ret = array();

		while($c = $this->fetchOne($col))
			$ret[] = $c;

		return $ret;
	}

	/**
	 * Return associative array of first result row
	 *
	 * @return array
	 */

	public function fetchRow()
	{
		return mysql_fetch_assoc($this->res);
	}

	/**
	 * Fetch all result rows.
	 *
	 * @return array
	 */

	public function fetchAll()
	{
		$ret = array();

		while($row = mysql_fetch_assoc($this->res))
			$ret[] = $row;

		return $ret;
	}

	/**
	 * Return all rows associated by given column(s). See http://query2.0o.cz for details.
	 *
	 * @param string $col1 - first assoc with this
	 * @param string $col2 - then assoc with this
	 * ...
	 *
	 * @return array
	 */

	public function fetchAssoc()
	{
		$cols = func_get_args();

		$arr = $this->fetchAll();
		$ret = array();

		foreach($arr as $row) {
			$cur =& $ret;

			foreach($cols as $col) {
				if(!isset($cur[$row[$col]]))
					$cur[$row[$col]] = array();

				$cur =& $cur[$row[$col]];
			}

			$cur[] = $row;
		}

		return $ret;
	}

	/**
	 * Return array("id" => "jmeno", ...) consisting of the first two columns
	 * of all result rows. Useful e.g. for fetching values for select box.
	 *
	 * @return array
	 */

	public function fetchPairs()
	{
		$ret = array();

		while($row = mysql_fetch_array($this->res))
			$ret[$row[0]] = $row[1];

		return $ret;
	}

	public function numRows() { return mysql_num_rows($this->res); }

	// Countable interface
	public function count() { return $this->numRows(); }

	// Iterator interface

	private $idx = 0; // generate some (for each row unique) key
	private $row; // current row
	
	/**
	 * Rewind the result set to the start (or to the given row). It's both
	 * directly callable and implementation of Iterator interface
	 *
	 * @param integer $row - to which row result set should be rewinded
	 */

	public function rewind($row = 0)
	{
		if(mysql_num_rows($this->res))
			mysql_data_seek($this->res, 0);

		$this->idx = 0;
	}

	public function current() { return $this->row; }
	public function key()     { return $this->idx; }
	public function next()    { $this->idx++; }

	public function valid() 
	{
		$this->row = $this->fetchRow();

		return $this->row ? true : false;
	}
}